#include "threadpool.h"
#include "server.h" 

void threadpoolInit(thread_pool_t* pthreadpool, int threadNum)
{
    pthreadpool->threadNumber = threadNum;
    pthreadpool->threads = (pthread_t*)calloc(threadNum, sizeof(pthread_t));
    queueInit(&pthreadpool->queue);
}

void threadpoolDestroy(thread_pool_t* pthreadpool)
{
    free(pthreadpool->threads);
    queueDestroy(&pthreadpool->queue);
}

void threadpoolStart(thread_pool_t * pthreadpool)
{
    for(int idx = 0; idx < pthreadpool->threadNumber; ++idx) {
        int ret = pthread_create(&pthreadpool->threads[idx],
                                 NULL, 
                                 threadFunc, 
                                 pthreadpool);
        THREAD_ERROR_CHECK(ret, "pthread_create");
    }
}

//线程执行的主函数
void* threadFunc(void* arg)
{
    printf("sub thread %ld is runing\n", pthread_self());
    thread_pool_t * pthreadpool = (thread_pool_t*)arg;
    while(1) {
        //从任务队列获取客户端的文件描述符，并循环执行其提供的命令
        int peerfd = taskDequeue(&pthreadpool->queue);
        //设标志位用来通知客户端命令执行情况
        int flag;
        //登录失败返回-1并直接关闭套接字，登录成功则返回用户id并发送标志位0
        int registerRet = Register(peerfd);
        if(registerRet < 0) {
            close(peerfd);
            continue;
        } else {
            flag = 0;
            Sendn(peerfd, &flag, sizeof(int));
        }
        //开始循环为客户端提供服务
        while(1) {
            //接收客户端的命令
            Train_t train;
            memset(&train, 0, sizeof(train));
            int ret = recv(peerfd, &train.lenth, sizeof(int), MSG_WAITALL);
            if(ret < 0){
                perror("recv");
                break;
            } else if(ret == 0) {
                break;
            }
            ret = recv(peerfd, train.buf, train.lenth, MSG_WAITALL);
            if(ret < 0){
                perror("recv");
                break;
            } else if(ret == 0) {
                break;
            }

            //解析命令，如果返回错误，则不必再调用相应接口
            char fileName[1024] = {0};
            ret = CommandAnalyse(train.buf, fileName);
            if(ret == -1) {
                continue;
            }
            printf("ret = %d\n", ret);

            //根据ret选择相应的接口，然后向客户端发送必要信息
            memset(&train, 0, sizeof(train));
            if(ret == _CDDIR) {
                flag = CdDir(fileName, registerRet);
                SendFlagOnly(flag, peerfd);
            } else if(ret == _LSDIR) {
                flag = LsDir(fileName, registerRet, train.buf);
                SendFlagAndMsg(flag, peerfd, &train);
            } else if(ret == _PWDDIR) {
                flag = PwdDir(train.buf, registerRet);
                SendFlagAndMsg(flag, peerfd, &train);
            } else if(ret == _RMFILE) {
                flag = RmFile(fileName, registerRet);
                SendFlagOnly(flag, peerfd);
            } else if(ret == _MKDIR) {
                flag = MkDir(fileName, registerRet);
                SendFlagOnly(flag, peerfd);
            } else if(ret == _GETFILE) {
                strcpy(train.buf,RecvFile(peerfd));
            } else if(ret == _PUTFILE) {
                strcpy(train.buf,SendFile(fileName,peerfd));
            }
        }
        //服务结束，关闭客户端套接字对应的文件描述符
        close(peerfd);
    }
    pthread_exit(0);
}

